package com.lagou.work.task03.angel.jobService.impl.dome;

import com.lagou.work.task03.angel.utils.DateUtils;
import com.lagou.work.task03.angel.utils.IOUtil;
import com.lagou.work.task03.angel.utils.ParsePropertiesFileUtil;
import com.lagou.work.task03.angel.utils.SelfDefiningClassLoader;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Date;
import java.util.Map;

/**
 * @author：dingyuan
 * @date：Created in 2022/4/14 20:54
 * @description：Server端对Master端发生来task进行处理
 * @version: 1.0
 */
public class ServerTaskRunnable implements Runnable {
    private static final String FIEL_END_NAME = ".txt";
    private Socket accept;
    private String num;
    public ServerTaskRunnable() {
    }

    public ServerTaskRunnable(Socket accept, String num) {
        this.accept = accept;
        this.num = num;
    }

    @Override
    public void run() {

        InputStream inputStream = null;
        PrintStream printStream = null;
        ByteArrayOutputStream byteArrOutStream = null;
        try {

            // 接收来自client端发生的计算任务(此次job是接收一个远程客户端通过mster角色发送的一个排序计算类)
            inputStream = accept.getInputStream();
            byteArrOutStream = (ByteArrayOutputStream) IOUtil.handleIOStream(inputStream, new ByteArrayOutputStream());

            // 准备计算需要的输入数据，本次job是通过IO流读取指定目录下的文件内容，对文件中的数据进行排序
            String arr = IOUtil.readFileFromLocal("D://input//test1.txt");

            // 自定义加载远程客户端发送的排序计算类，并通过反射机制获取该类中的排序方法，对上述读取到的文件数据进行排序
            SelfDefiningClassLoader classLoader = new SelfDefiningClassLoader(byteArrOutStream.toByteArray());
            Class bubbleSortClass = classLoader.findClass("BubbleSort");
            Object obj = bubbleSortClass.getConstructor().newInstance();
            Method sortMethod = bubbleSortClass.getMethod("sort", String.class);
            String invoke = (String) sortMethod.invoke(obj, arr);
            Map<String, String> stringStringMap = new ParsePropertiesFileUtil().readProperties("angle/server-sit.properties");
            synchronized (this) {
                // 将排序结果输出到指定目录路径下（指定的目录通过配置文件server-sit.properties设置），输出的文件名需自定义
                String time = DateUtils.date2StrByFormatParam(new Date(), "yyyyMMddHHmmss");
                String out2Path = stringStringMap.get("outPath");
                String outPutPath = out2Path + "sortResult" + num + "_" + time + FIEL_END_NAME;

                // 将排序后的结果通过IO流输出到目标文件
                IOUtil.writeFile2Local(outPutPath, invoke);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtil.close(accept, inputStream, byteArrOutStream, printStream);
        }
    }

}
